/*
 * File: sexp.h
 * -----------
 * This interface defines an abstract type for s-expressions.
 * S-expressions provides clients with a general facility for
 * manipulating list structure. The fundamental type defined
 * by the abstraction is the s-expression, which is represented
 * by the type sExpADT. The concept of an s-expression is
 * derived from the programming language LISP.
 */

#ifndef _sExp_h
#define _sExp_h

#include "genlib.h"

/*
 * Constant: NIL
 * -------------
 * This constant is identical to C's NULL, but the name NIL is
 * more traditional when referring to list structure.
 */

#define NIL NULL

/*
 * Type: sExpADT
 * -------------------
 * This type is the abstract data type representing an
 * s-expression, which is defined recursvely to have one
 * of the following forms:
 *
 * 1. The constant NIL
 * 2. A number, which is defined by its value
 * 3. An atom, which is uniquely defined by its name
 * 4. A dotted pair consisting of two s-expressions
 */

typedef struct sExpCDT *sExpADT;

/*
 * Type: sExpTypeT
 * --------------
 * This enumeration type encompasses the possible s-expression types.
 */

typedef enum {
    NilType,
    NumberType,
    AtomType,
    DtprType
} sExpTypeT;


void InitSymbolTable(void);
/*
 * Function: SExpType
 * Usage: type = SExpType(sx);
 * ---------------------------
 * This function returns a value of type sExpTypeT that
 * corresponds to the type of the s-expression sx.
 */

sExpTypeT SExpType(sExpADT sx);

/*
 * Functions: Car, Cdr
 * Usage: car = Car(sx)
 *        cdr = Cdr(sx)
 * --------------------
 * The Car and Cdr functions return the left and right components
 * of the s-expression sx, which must be a dotted pair.
 */

sExpADT Car(sExpADT sx);
sExpADT Cdr(sExpADT sx);

/*
 * Function: Cons
 * Usage: sx = Cons(car, cdr);
 * ---------------------------
 * This function creates a new dotted pair s-expression with the
 * specified car and cdr fields.
 */

sExpADT Cons(sExpADT car, sExpADT cdr);

/*
 * Function: StringToAtom
 * Usage: atom = StringToAtom(str);
 * --------------------------------
 * This function returns an atom with the name str. Because atoms
 * are unique, a second call to StringToAtom with the same string
 * will return the same atom instead of creating a new one.
 */

sExpADT StringToAtom(string name);

/*
 * Function: AtomToString
 * Usage: atom = AtomToString(str);
 * --------------------------------
 * This function returns the name of the atom.
 */

string AtomToString(sExpADT atom);

/*
 * Functions: NumbertoSExp, SExpToNumber
 * Usage: sx = NumberToSExp(n);
 *        n  = SExpToNumber(sx);
 * -----------------------------
 * The NumberToSExp function allocates a new s-expression of
 * the type NumberType with the value n. SExpToNumber selects the
 * value from a numeric s-expression.
 */

sExpADT NumberToSExp(int n);
int SExpToNumber(sExpADT sx);

#endif
